﻿/// <reference path="TsLinq.d.ts" />
/// <reference path="List.ts" />
/// <reference path="Linq.ts" />
/// <reference path="DefaultComparer.ts" />
/// <reference path="KeyValuePair.ts" />
var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var Dictionary = (function (_super) {
    __extends(Dictionary, _super);
    function Dictionary() {
        _super.apply(this, arguments);
    }
    //
    //  Adds a new entry.
    //
    Dictionary.prototype.add = function (key, value) {
        if (typeof value === "undefined") { value = undefined; }
        if (this.containsKey(key)) {
            throw new Error('Can not add already added key <' + key.toString() + '>');
        }
        _super.prototype.push.call(this, new KeyValuePair(key, value));
    };

    //
    //  Counts all elements. If an expression is given, the system counts all elements which are fitting this expression.
    //
    Dictionary.prototype.count = function (expr) {
        return _super.prototype.count.call(this, expr);
    };

    //
    //  Returns a value wherever the value list contains the given value.
    //
    Dictionary.prototype.containsValue = function (value, valueComparer) {
        return _super.prototype.contains.call(this, new KeyValuePair(null, value), new KeyValueComparerForValue(valueComparer));
    };

    //
    //  Returns whenever the key was added to the collection. Optionally you can add a comparer to find the correct key.
    //
    Dictionary.prototype.containsKey = function (key, keyComparer) {
        return _super.prototype.contains.call(this, new KeyValuePair(key, null), new KeyValueComparerForKey(keyComparer));
    };

    //
    //  Clears all items in the dictionary.
    //
    Dictionary.prototype.clear = function () {
        _super.prototype.clear.call(this);
    };

    //
    //  Removes the entry with the specified key.
    //
    Dictionary.prototype.removeKey = function (key, comp) {
        var index = this.indexOf(new KeyValuePair(key, null), new KeyValueComparerForKey(comp));
        if (index > -1) {
            var value = this.tryGetValue(key, comp);
            this._items.splice(index, 1);
            return value;
        }
        throw new Error('Key <' + key.toString() + '> was not found for removing');
    };

    //
    //  tries returning a value with a specific key. If the value does not exists, the method returns null.
    //
    Dictionary.prototype.tryGetValue = function (key, comp) {
        var comparer = comp || new DefaultComparer();
        var foundValue = null;
        this.forEach(function (kvp) {
            if (comparer.compare(key, kvp.key) == 0) {
                foundValue = kvp.value;
                return false;
            }
        });
        return foundValue;
    };

    //
    //  Returns the first element index of the entry with the matching key.
    //
    Dictionary.prototype.indexOfKey = function (key, comp) {
        return _super.prototype.indexOf.call(this, new KeyValuePair(key, null), new KeyValueComparerForKey(comp || new DefaultComparer()));
    };

    //
    //  Returns the value of the given key. If a comparer is specified, it will used to compare the keys.
    //
    Dictionary.prototype.get = function (key, comp) {
        var index = this.indexOfKey(key, comp);
        if (index < 0) {
            if (console && console.log) {
                console.log(key);
            }
            throw new Error('Key <' + key + '> was not found. Look into console in chrome for more infos.');
        }
        return this.elementAt(index).value;
    };

    //
    //  Returns an array of all keys.
    //
    Dictionary.prototype.getKeys = function () {
        return this.select(function (kvp) {
            return kvp.key;
        }).toArray();
    };

    //
    //  Returns an array of all values in the dictionary.
    //
    Dictionary.prototype.getValues = function () {
        return this.select(function (kvp) {
            return kvp.value;
        }).toArray();
    };
    return Dictionary;
})(List);
